#include "Camera.h"



Camera::Camera() :
	m_Pos(0.f, 0.f, 0.f),
	m_Look(0.f, 0.f, 1.f),
	m_Right(1.f, 0.f, 0.f),
	m_Up(0.f, 1.f, 0.f),
	Type(CameraType::LANDOBJECT)
{
}


Camera::~Camera()
{
}

void Camera::SetLens(float fovY, float aspect, float nearz, float farz)
{
	m_fovY = fovY;
	m_aspect = aspect;
	m_nearZ = nearz;
	m_farZ = farz;
	XMMATRIX P = XMMatrixPerspectiveFovLH(fovY, aspect, nearz, farz);
	XMStoreFloat4x4(&m_Proj, P);
}

void Camera::LookAtXM(XMVECTOR pos, XMVECTOR lookAt, XMVECTOR worldUp)
{
	XMVECTOR look = XMVector3Normalize(lookAt - pos);
	XMVECTOR right = XMVector3Normalize(XMVector3Cross(worldUp, look));
	XMVECTOR up = XMVector3Cross(look, right);

	XMStoreFloat3(&m_Pos, pos);
	XMStoreFloat3(&m_Look, look);
	XMStoreFloat3(&m_Right, right);
	XMStoreFloat3(&m_Up, up);
	XMMATRIX g_MeshView = XMMatrixLookAtLH(pos, lookAt, worldUp);
	XMStoreFloat4x4(&m_View, g_MeshView);
}

void Camera::Walk(float dist)
{
	XMVECTOR Pos = XMLoadFloat3(&m_Pos);
	//XMVECTOR look = XMLoadFloat3(&m_Look);
	XMFLOAT3 Flook = m_Look;
	if (Type == CameraType::LANDOBJECT)
	{
		Flook.y = 0;
		XMVECTOR look = XMLoadFloat3(&Flook);
		Pos += look* XMVectorReplicate(dist);
		XMStoreFloat3(&m_Pos, Pos);
	}
	else if (Type == CameraType::AIRCRAFT)
	{
		XMVECTOR look = XMLoadFloat3(&m_Look);
		Pos += look* XMVectorReplicate(dist);
		XMStoreFloat3(&m_Pos, Pos);
	}
}

void Camera::Strafe(float dist)
{
	XMVECTOR Pos = XMLoadFloat3(&m_Pos);
	//XMVECTOR look = XMLoadFloat3(&m_Look);
	XMFLOAT3 FRight = m_Right;
	if (Type == CameraType::LANDOBJECT)
	{
		FRight.y = 0;
		XMVECTOR right = XMLoadFloat3(&FRight);
		Pos += right* XMVectorReplicate(dist);
		XMStoreFloat3(&m_Pos, Pos);
	}
	else if (Type == CameraType::AIRCRAFT)
	{
		XMVECTOR rigth = XMLoadFloat3(&m_Right);
		Pos += rigth* XMVectorReplicate(dist);
		XMStoreFloat3(&m_Pos, Pos);
	}
}

void Camera::Fly(float dist)
{
	XMVECTOR Pos = XMLoadFloat3(&m_Pos);
	XMVECTOR up = XMLoadFloat3(&m_Up);
	if (Type == CameraType::LANDOBJECT)
	{
		m_Pos.y += dist;

	}
	else if (Type == CameraType::AIRCRAFT)
	{
		Pos += up* XMVectorReplicate(dist);
		XMStoreFloat3(&m_Pos, Pos);
	}
}

void Camera::Pitch(float angle)
{
	XMMATRIX rotation = XMMatrixRotationAxis(XMLoadFloat3(&m_Right), angle);

	XMStoreFloat3(&m_Up, XMVector3TransformNormal(XMLoadFloat3(&m_Up), rotation));
	XMStoreFloat3(&m_Look, XMVector3TransformNormal(XMLoadFloat3(&m_Look), rotation));
}

void Camera::Yaw(float angle)
{
	if (Type == CameraType::LANDOBJECT)
	{
		XMMATRIX rotation = XMMatrixRotationY(angle);
		XMStoreFloat3(&m_Look, XMVector3TransformNormal(XMLoadFloat3(&m_Look), rotation));
		XMStoreFloat3(&m_Up, XMVector3TransformNormal(XMLoadFloat3(&m_Up), rotation));
		XMStoreFloat3(&m_Right, XMVector3TransformNormal(XMLoadFloat3(&m_Right), rotation));
	}
	else if (Type == CameraType::AIRCRAFT)
	{
		XMMATRIX rotation = XMMatrixRotationAxis(XMLoadFloat3(&m_Up), angle);

		XMStoreFloat3(&m_Right, XMVector3TransformNormal(XMLoadFloat3(&m_Right), rotation));
		XMStoreFloat3(&m_Look, XMVector3TransformNormal(XMLoadFloat3(&m_Look), rotation));
	}
}

void Camera::UpdateViewMatrix()
{
	XMVECTOR r = XMLoadFloat3(&m_Right);
	XMVECTOR u = XMLoadFloat3(&m_Up);
	XMVECTOR l = XMLoadFloat3(&m_Look);
	XMVECTOR p = XMLoadFloat3(&m_Pos);

	r = XMVector3Normalize(XMVector3Cross(u, l));
	u = XMVector3Normalize(XMVector3Cross(l, r));
	l = XMVector3Normalize(l);

	float x = -XMVectorGetX(XMVector3Dot(p, r));
	float y = -XMVectorGetX(XMVector3Dot(p, u));
	float z = -XMVectorGetX(XMVector3Dot(p, l));

	XMStoreFloat3(&m_Right, r);
	XMStoreFloat3(&m_Up, u);
	XMStoreFloat3(&m_Look, l);
	XMStoreFloat3(&m_Pos, p);

	m_View(0, 0) = m_Right.x;    m_View(0, 1) = m_Up.x;    m_View(0, 2) = m_Look.x;     m_View(0, 3) = 0;
	m_View(1, 0) = m_Right.y;    m_View(1, 1) = m_Up.y;    m_View(1, 2) = m_Look.y;     m_View(1, 3) = 0;
	m_View(2, 0) = m_Right.z;    m_View(2, 1) = m_Up.z;    m_View(2, 2) = m_Look.z;     m_View(2, 3) = 0;
	m_View(3, 0) = x;            m_View(3, 1) = y;         m_View(3, 2) = z;            m_View(3, 3) = 1;
}
